package main

import (
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
	"image/color"
	"log"
)

/*
Instead of building a new component by extending an existing widget, as we did in the
previous section, we could build one from scratch. Any component that implements
the fyne.Widget interface can be used as a widget in a Fyne application. To ease
development, there is a widget.BaseWidget definition that we can inherit from. Let's
start by defining the behavior of a new widget—the three-state checkbox.
*/

type CheckState int

const (
	CheckOff CheckState = iota
	CheckOn
	CheckIndeterminate
)

type ThreeStateCheck struct {
	widget.BaseWidget
	State CheckState
}

/*
 实现接口 WidgetRenderer
*/
type threeStateRender struct {
	check *ThreeStateCheck
	img   *canvas.Image
}
/*
 鼠标点击事件，每次鼠标点击都会触发，正常图标都应该实现，当点击图标的时候响应点击事件
*/
func (c *ThreeStateCheck) Tapped(_ *fyne.PointEvent) {
	if c.State == CheckIndeterminate {
		c.State = CheckOff
	} else {
		c.State++
	}
	c.Refresh()
}

func (c *ThreeStateCheck) CreateRenderer() fyne.WidgetRenderer {
	r := &threeStateRender{c, &canvas.Image{}}
	r.updateImage()
	return r
}

func NewThreeStateCheck() *ThreeStateCheck {
	c := &ThreeStateCheck{}
	// 使用扩展
	c.ExtendBaseWidget(c)
	return c
}


func (t *threeStateRender) BackgroundColor() color.Color {
	return color.Transparent
}

func (t *threeStateRender) Destroy() {

}

func (t *threeStateRender) Layout(_ fyne.Size) {
	t.img.Resize(t.MinSize())
}

func (t *threeStateRender) MinSize() fyne.Size {
	return fyne.NewSize(theme.IconInlineSize(), theme.IconInlineSize())
}

func (t *threeStateRender) Objects() []fyne.CanvasObject {
	return []fyne.CanvasObject{t.img}
}

/*
	每次事件触发都会调用  Refresh
*/
func (t *threeStateRender) Refresh() {
	t.updateImage()
}

func (t *threeStateRender) updateImage() {
	defer t.img.Refresh()

	switch t.check.State {
	case CheckOn:
		t.img.Resource = theme.CheckButtonCheckedIcon()
	case CheckIndeterminate:
		res, err := fyne.LoadResourceFromPath("load.svg")
		if err != nil {
			log.Println("Failed to load indeterminate resource")
			return
		}
		t.img.Resource = theme.NewThemedResource(res)
	default:
		t.img.Resource = theme.CheckButtonIcon()
	}
}

func main() {
	a := app.New()
	w := a.NewWindow("Three State")

	w.SetContent(NewThreeStateCheck())
	w.ShowAndRun()
}
